<template>
  <div class="container">
    <div class="content-wrapper">
      <div class="flex-container">
        <!-- 左侧课表 -->
        <div class="left-panel">
          <div class="header">
            <div class="title-container">
              <h1 class="title">{{ orgData.org_name }}</h1>
              <p class="subtitle">
                {{ orgData.course_year }}学期第{{ orgData.course_term }}学期无课表
                <el-tooltip
                  content="单元格内时间段的成员均无课，深色单元格表示该时间段所有成员均无课，右侧成员列表中，双击可高亮显示该成员无课时间段。注：体能训练计入无课"
                  placement="right"
                  popper-style="max-width: 300px; font-size: 14px; line-height: 1.5; white-space: pre-line;"
                >
                  <el-icon style="vertical-align: middle; margin-left: 8px">
                    <QuestionFilled />
                  </el-icon>
                </el-tooltip>
              </p>
            </div>
            <div class="week-selector">
              <div class="week-buttons">
                <el-button @click="currentWeek--" size="mini" :disabled="currentWeek === 1">
                  <i class="el-icon-arrow-left"></i>上一周
                </el-button>
                <p>第{{ currentWeek.toString().padStart(2, "0") }}周</p>
                <el-button @click="currentWeek++" size="mini" :disabled="currentWeek === 18">
                  下一周<i class="el-icon-arrow-right"></i>
                </el-button>
              </div>
              <el-slider v-model="currentWeek" :step="1" show-stops :min="1" :max="18" />
            </div>
            <div class="schedule-controls">
              <el-switch v-model="showWeekend" active-text="显示周末" inactive-text="隐藏周末" />
              <el-switch v-model="showLunch" active-text="显示午休" inactive-text="隐藏午休" />
            </div>
          </div>
          <div class="schedule-grid" :style="gridStyle">
            <div class="time-slot-header"></div>
            <div
              v-for="(day, index) in weekDays"
              :key="day"
              class="day-header"
              v-show="showWeekend || (day !== '周六' && day !== '周日')"
            >
              {{ day }}（{{ currentWeekDates[index] }}）
            </div>
            <template v-for="schedule in filteredSchedules" :key="schedule.time">
              <div class="time-slot">
                {{ schedule.time }}
              </div>
              <template v-for="(students, day) in schedule" :key="day">
                <div
                  v-if="day !== 'time' && (showWeekend || (day !== 'saturday' && day !== 'sunday'))"
                  :class="[
                    'course-cell',
                    {
                      highlight: isHighlighted(schedule.time, day),
                      'full-student-cell': Array.isArray(students) && showMembers <= students.filter((student: any) => student.weeks.includes(currentWeek)).length,
                    },
                  ]"
                >
                  <div class="students-wrapper">
                    <template v-if="Array.isArray(students) && students.length">
                      <el-tag
                        v-for="(student, index) in students
                          .filter((student: any) => student.weeks.includes(currentWeek))
                          .slice(0, showNum)"
                        :key="index"
                        size="small"
                        class="student-tag"
                        :style="{
                          backgroundColor: getColorForStudent(student.name),
                          color: getTextColor(getColorForStudent(student.name))
                        }"
                      >
                        {{ student.name }}
                      </el-tag>
                      <el-tag
                        v-if="students.filter((student: any) => student.weeks.includes(currentWeek)).length > showNum"
                        size="small"
                        class="more-tag"
                      >
                        +{{ students.filter((student: any) => student.weeks.includes(currentWeek)).length - showNum }}
                      </el-tag>
                    </template>
                  </div>
                </div>
              </template>
            </template>
          </div>
        </div>
        <!-- 右侧列表 -->
        <div class="right-panel">
          <div class="header">
            <h2 class="title">组织成员</h2>
            <el-input v-model="searchText" placeholder="搜索成员" class="search-input" :prefix-icon="Search" />
          </div>
          <!-- 突出显示成员无课时间 滑块控制人数-->
          <div class="slider-container">
            <el-slider
              v-model="showMembers"
              :min="1"
              :max="allowMembers"
              :step="1"
              show-stops
              :format-tooltip="(value: any) => `突出显示至少 ${value} 人同时无课的时间`"
              style="color: #1f1f1f"
            />
          </div>
          <div class="notices-list">
            <div
              v-for="member in filteredMembers"
              :key="member.member_id"
              class="notice-card"
              @dblclick="highlightSchedule(member)"
            >
              <div class="notice-header">
                <el-tag
                  :style="{
                    backgroundColor: getColorForStudent(
                      member.personal_info === null ? '未获取课表' : member.personal_info.name
                    ),
                    borderColor: 'transparent',
                    fontSize: '17px',
                    color: getTextColor(
                      getColorForStudent(member.personal_info === null ? '未获取课表' : member.personal_info.name)
                    )
                  }"
                  size="default"
                  effect="dark"
                >
                  {{ member.personal_info === null ? "未获取课表" : member.personal_info.name }}
                </el-tag>
                <el-popover
                  v-model:visible="member.popoverVisible"
                  title="警告"
                  width="auto"
                  trigger="click"
                  placement="left"
                  :disabled="member.role === 'admin'"
                >
                  <p>
                    确认删除用户
                    {{ member.personal_info === null ? "xx" : member.personal_info.name }}?
                  </p>
                  <div style="text-align: right; margin-top: 10px">
                    <el-button size="mini" @click="member.popoverVisible = false">取消</el-button>
                    <el-button size="mini" type="primary" @click="confirmDelete(member)">确定</el-button>
                  </div>
                  <template #reference>
                    <el-tag
                      :style="{
                        backgroundColor: getColorForRole(member.role),
                        borderColor: 'transparent',
                        color: getTextColor(getColorForRole(member.role)),
                        userSelect: 'none'
                      }"
                      size="default"
                      effect="dark"
                    >
                      {{ member.role }}
                    </el-tag>
                  </template>
                </el-popover>
              </div>
              <div class="member-info">
                <p class="notice-content">用户ID: {{ member.user.user_id }}</p>
                <p class="notice-content">用户名/学号: {{ member.user.username }}</p>
                <p class="notice-content">
                  专业:
                  {{ member.personal_info === null ? "未获取课表" : member.personal_info.major }}
                </p>
                <p class="notice-content">邮箱: {{ member.user.email }}</p>
                <p class="notice-content">加入时间: {{ member.joined_at }}</p>
              </div>
            </div>
          </div>
          <div class="pagination-container">
            <!-- 显示多少条 -->
            <el-pagination
              :total="members.length"
              :page-size="members.length"
              layout="total"
              style="text-align: right"
            />
            <!-- 按钮导出无课表 -->
            <el-popover
              v-model:visible="showExportPopover"
              title="导出无课表"
              width="180"
              trigger="click"
              style="text-align: center"
            >
              <div>
                <div style="display: flex; align-items: center; gap: 10px; margin-bottom: 10px">
                  <p>开始周</p>
                  <el-input-number
                    v-model="startWeek"
                    :min="1"
                    :max="endWeek"
                    label="开始周"
                    style="width: 100px"
                    size="small"
                    @wheel.prevent="(event: any) => { event.deltaY < 0 ? startWeek++ : startWeek-- }"
                  />
                </div>
                <div style="display: flex; align-items: center; gap: 10px">
                  <p>结束周</p>
                  <el-input-number
                    v-model="endWeek"
                    :min="startWeek"
                    :max="18"
                    label="结束周"
                    style="width: 100px"
                    size="small"
                    @wheel.prevent="(event: any) => { event.deltaY < 0 ? endWeek++ : endWeek-- }"
                  />
                </div>
              </div>
              <div style="display: flex; justify-content: space-between; margin-top: 10px">
                <el-button size="small" @click="showExportPopover = false">取消</el-button>
                <el-button size="small" type="primary" @click="confirmExport">确定</el-button>
              </div>
              <template #reference>
                <el-button type="primary" size="small">导出无课表</el-button>
              </template>
            </el-popover>
            <!-- 按钮跳转到排班页面 -->
            <el-button type="primary" size="small" @click="goToScheduling">排班</el-button>
          </div>
        </div>
      </div>
    </div>
    <!-- 课程详情弹窗 -->
    <!-- <el-dialog v-model="showCourseDetail" title="课程详情" width="30%">
      <template v-if="selectedCourse">
        <div class="dialog-content">
          <div class="detail">
            <div class="label">课程名称</div>
            <div class="value">{{ selectedCourse.name }}</div>
          </div>
          <div class="detail">
            <div class="label">任课教师</div>
            <div class="value">{{ selectedCourse.teacher }}</div>
          </div>
          <div class="detail">
            <div class="label">教室</div>
            <div class="value">{{ selectedCourse.room }}</div>
          </div>
          <div class="detail">
            <div class="label">课程类型</div>
            <div class="value">{{ selectedCourse.type }}</div>
          </div>
        </div>
      </template>
    </el-dialog> -->
  </div>
</template>

<script lang="ts" setup>
  import { ref, computed, onMounted } from "vue";
  import { Search } from "@element-plus/icons-vue";
  import "element-plus/theme-chalk/el-select.css";
  import "element-plus/theme-chalk/el-option.css";
  import { useRoute, useRouter } from "vue-router";
  import api from "../axios/api";
  import { ElLoading, ElMessage } from "element-plus";
  import generateExcel from "./export_excel";

  const route = useRoute();
  const router = useRouter();
  const orgId = ref(route.params.orgId as string);
  const orgData = ref(
    JSON.parse(localStorage.getItem("orgData") || "[]").find((item: any) => item.org_id.toString() === orgId.value) ||
      {}
  );
  const week_start_date = ref(""); // 周开始日期格式：2024-09-02
  const noClassSchedules = ref<any[]>([]); // 用于存储无课表数据

  const goToScheduling = () => {
    router.push(`/SchedulingWork/${orgId.value}`);
  };

  const showExportPopover = ref(false);
  const startWeek = ref(1);
  const endWeek = ref(18);

  const confirmExport = () => {
    showExportPopover.value = false;
    generateExcel(noClassSchedules.value, startWeek.value, endWeek.value, orgData.value.org_name);
  };

  // 计算当前周每日日期
  const currentWeekDates = computed(() => {
    if (!week_start_date.value) return new Array(7).fill("--");
    try {
      const startDate = new Date(week_start_date.value);
      if (isNaN(startDate.getTime())) return new Array(7).fill("--");

      // 计算当前周偏移量
      const weekOffset = (currentWeek.value - 1) * 7;
      const currentWeekStart = new Date(startDate);
      currentWeekStart.setDate(currentWeekStart.getDate() + weekOffset);

      return Array.from({ length: 7 }, (_, i) => {
        const date = new Date(currentWeekStart);
        date.setDate(date.getDate() + i);
        return `${(date.getMonth() + 1).toString().padStart(2, "0")}/${date.getDate().toString().padStart(2, "0")}`;
      });
    } catch {
      return new Array(7).fill("--");
    }
  });
  const showMembers = ref(0);
  const allowMembers = ref(10);
  const showWeekend = ref(false);
  const showLunch = ref(false);
  const showNum = computed(() => {
    return 4 + (showWeekend.value ? 0 : 1) + (showLunch.value ? 0 : 2);
  });

  // 动态计算 grid 样式
  const gridStyle = computed(() => {
    const dayCount = showWeekend.value ? 7 : 5; // 显示7天或5天
    return {
      gridTemplateColumns: `0.7fr repeat(${dayCount}, 1fr)`
    };
  });

  const filteredSchedules = computed(() => {
    return schedules.value.filter(schedule => {
      if (schedule.time === "5-6节\n12:30-13:50") {
        return showLunch.value;
      }
      return true;
    });
  });

  interface Student {
    name: string;
    weeks: number[];
  }

  interface Schedule {
    time: string;
    monday: Student[];
    tuesday: Student[];
    wednesday: Student[];
    thursday: Student[];
    friday: Student[];
    saturday: Student[];
    sunday: Student[];
  }

  interface Member {
    member_id: number;
    org_id: number;
    role: string;
    joined_at: string;
    user: {
      user_id: number;
      username: string;
      email: string;
      role: string;
      is_active: boolean;
      created_at: string;
      updated_at: string;
    };
    personal_info: {
      name: string;
      grade: string;
      major: string;
      student_id: string;
    };
    popoverVisible: boolean;
  }

  const currentWeek = ref(1);
  const searchText = ref("");
  const weekDays = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"];

  const schedules = ref<Schedule[]>([]);

  const refrest_data = async () => {
    const loading = ElLoading.service({
      lock: true,
      text: "加载中...",
      background: "rgba(0, 0, 0, 0.7)"
    });
    try {
      // 获取成员数据
      const membersData = await api.getOrgMembers(orgId.value);
      members.value = membersData.data;
      showMembers.value = members.value.length;
      allowMembers.value = members.value.length;
      // 获取无课表数据
      const res = await api.getOrgNoClassSchedules(orgId.value);
      week_start_date.value = res.data.week_start_date.replace(/年|月/g, "-").replace("日", "");
      noClassSchedules.value = res.data.no_class_schedule;
      // console.log(JSON.stringify(noClassSchedules.value))
      // 处理课程表数据
      schedules.value = noClassSchedules.value.map((item: any) => ({
        time: item.time,
        monday: item.monday,
        tuesday: item.tuesday,
        wednesday: item.wednesday,
        thursday: item.thursday,
        friday: item.friday,
        saturday: item.saturday,
        sunday: item.sunday
      }));
    } catch (error) {
      ElMessage.error("数据加载失败");
    } finally {
      loading.close();
    }
  };

  onMounted(async () => {
    await refrest_data();
  });

  const members = ref<Member[]>([]);

  const filteredMembers = computed(() => {
    if (!searchText.value) return members.value;
    return members.value.filter(
      (member: any) =>
        member.personal_info.name.toLowerCase().includes(searchText.value.toLowerCase()) ||
        member.personal_info.student_id.toLowerCase().includes(searchText.value.toLowerCase()) ||
        member.user.username.toLowerCase().includes(searchText.value.toLowerCase()) ||
        member.user.email.toLowerCase().includes(searchText.value.toLowerCase()) ||
        member.personal_info.major.toLowerCase().includes(searchText.value.toLowerCase())
    );
  });

  const getColorForStudent = (name: string) => {
    // 简单的哈希函数
    const hash = name.split("").reduce((acc, char) => {
      return acc + char.charCodeAt(0);
    }, 0);

    // 使用哈希值生成颜色
    let color = `#${((hash * 1234567) % 0xffffff).toString(16).padStart(6, "0")}`;

    // 将 HEX 转换为 HSL
    const hexToHsl = (hex: string) => {
      hex = hex.replace("#", "");
      const r = parseInt(hex.substring(0, 2), 16) / 255;
      const g = parseInt(hex.substring(2, 4), 16) / 255;
      const b = parseInt(hex.substring(4, 6), 16) / 255;

      const max = Math.max(r, g, b);
      const min = Math.min(r, g, b);
      let h = 0,
        s = 0,
        l = (max + min) / 2;

      if (max !== min) {
        const d = max - min;
        s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
        switch (max) {
          case r:
            h = (g - b) / d + (g < b ? 6 : 0);
            break;
          case g:
            h = (b - r) / d + 2;
            break;
          case b:
            h = (r - g) / d + 4;
            break;
        }
        h /= 6;
      }

      return [h * 360, s * 100, l * 100];
    };

    // 将 HSL 转换为 HEX
    const hslToHex = (h: number, s: number, l: number) => {
      l /= 100;
      const a = (s * Math.min(l, 1 - l)) / 100;
      const f = (n: number) => {
        const k = (n + h / 30) % 12;
        const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
        return Math.round(255 * color)
          .toString(16)
          .padStart(2, "0");
      };
      return `#${f(0)}${f(8)}${f(4)}`;
    };

    // 调整亮度
    const [h, s, l] = hexToHsl(color);
    const newL = Math.min(80, l + 20); // 增加亮度，但不超过 80%

    // 返回新的颜色
    return hslToHex(h, s, newL);
  };

  const getColorForRole = (role: string) => {
    switch (role) {
      case "admin":
        return "#AC4944"; // 浅蓝色
      case "member":
        return "#1F2533"; // 浅绿色
      default:
        return "#f5f5f5"; // 默认灰色
    }
  };

  // 计算亮度
  const getLuminance = (hexColor: string): number => {
    const hex = hexColor.replace("#", "");
    const r = parseInt(hex.substring(0, 2), 16) / 255;
    const g = parseInt(hex.substring(2, 4), 16) / 255;
    const b = parseInt(hex.substring(4, 6), 16) / 255;
    return 0.2126 * r + 0.7152 * g + 0.0722 * b;
  };

  // 根据背景颜色获取文字颜色
  const getTextColor = (backgroundColor: string): string => {
    const luminance = getLuminance(backgroundColor);
    return luminance > 0.5 ? "#000000" : "#ffffff";
  };

  const highlightedCells = ref<{ time: string; day: string }[]>([]);

  const sortStudentByName = (name: string) => {
    schedules.value = schedules.value.map(schedule => {
      // 创建新的周几数据容器
      const sortedDays: Partial<Schedule> = {};

      // 遍历周一到周日
      const weekDays = ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"] as const;

      weekDays.forEach(day => {
        // 取出当前天的学生数组
        const students = schedule[day];

        // 分离目标学生和其他学生
        const targetStudent = students.find(s => s.name === name);
        const otherStudents = students.filter(s => s.name !== name);

        // 重新组合数组（保持非目标学生的原始顺序）
        sortedDays[day] = targetStudent ? [targetStudent, ...otherStudents] : [...students];
      });

      // 返回新对象保持响应式更新
      return {
        time: schedule.time,
        ...sortedDays
      } as Schedule;
    });
  };

  const highlightSchedule = (member: Member) => {
    console.log("触发");
    if (member.personal_info === null) {
      ElMessage.warning(`该成员[${member.user.username}]未获取课表`);
      return;
    }
    const color = getColorForStudent(member.personal_info.name);
    // 清除高亮
    highlightedCells.value = [];
    const cellsToHighlight: any[] = [];
    schedules.value.forEach((schedule: any) => {
      Object.entries(schedule).forEach(([key, value]: any) => {
        if (key !== "time") {
          for (const student of value) {
            if (student.name === member.personal_info.name && student.weeks.includes(currentWeek.value)) {
              cellsToHighlight.push({ time: schedule.time, day: key });
            }
          }
        }
      });
    });

    // 将选择的名字排序到第一个
    sortStudentByName(member.personal_info.name);

    highlightedCells.value = cellsToHighlight;

    // 动态生成 CSS
    const styleSheet = document.styleSheets[0];
    const keyframes = `
    @keyframes flash {
      0%, 100% {
        background-color: #ffffff;
      }
      50% {
        background-color: ${color};
      }
    }
  `;
    styleSheet.insertRule(keyframes, styleSheet.cssRules.length);

    setTimeout(() => {
      highlightedCells.value = [];
      // 移除动态生成的 CSS
      styleSheet.deleteRule(styleSheet.cssRules.length - 1);
    }, 3000); // 3秒后清除高亮
  };

  const isHighlighted = (time: string, day: string) => {
    return highlightedCells.value.some(cell => cell.time === time && cell.day === day);
  };

  const confirmDelete = async (member: Member) => {
    const memberName = member.personal_info.name;
    console.log(member, orgId.value);
    // 在这里添加删除用户的逻辑
    const res = await api.deleteMember(member.user.user_id.toString(), orgId.value.toString());
    if (res.status === 200) {
      ElMessage.success(`删除用户${memberName}成功`);
    } else {
      ElMessage.error(`删除用户${memberName}失败`);
    }
    member.popoverVisible = false;
    await refrest_data();
  };
</script>

<style scoped>
  /* 全局容器 */
  .container {
    min-height: 90%;
    background-color: #f9fafb; /* bg-gray-50 */
    padding: 1rem 0; /* py-8 */
  }

  /* 内容包装器 */
  .content-wrapper {
    max-width: 100%; /* max-w-7xl */
    margin: 0 auto; /* mx-auto */
    padding: 0 1rem; /* px-4 */
  }

  /* 弹性布局容器 */
  .flex-container {
    display: flex;
    gap: 1.5rem; /* gap-6 */
  }

  /* 左侧面板 */
  .left-panel {
    width: 80%; /* w-[70%] */
    background-color: #ffffff; /* bg-white */
    border-radius: 0.5rem; /* rounded-lg */
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); /* shadow-sm */
    padding: 1.5rem; /* p-6 */
  }

  /* 右侧面板 */
  .right-panel {
    width: 20%; /* w-[30%] */
    background-color: #ffffff; /* bg-white */
    border-radius: 0.5rem; /* rounded-lg */
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); /* shadow-sm */
    padding: 1.5rem; /* p-6 */
    height: 100%;
  }

  /* 头部样式 */
  .header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 1rem; /* mb-6 */
  }

  /* 标题样式 */
  .title {
    font-size: 1.8rem; /* 更大的字体 */
    font-weight: bold; /* 加粗 */
    color: #111827; /* 黑色 */
    margin-bottom: 0.25rem; /* 与副标题的间距 */
  }

  /* 副标题样式 */
  .subtitle {
    font-size: 1rem; /* 较小的字体 */
    color: #6b7280; /* 灰色 */
    margin-top: 0; /* 紧跟标题 */
    margin-bottom: 1rem; /* 紧跟标题 */
    /* 允许换行 */
    white-space: pre-line;
  }

  /* 周数选择器 */
  .week-selector {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.5rem; /* 调整间距 */
  }

  /* 周数选择器按钮 */
  .week-buttons {
    display: flex;
    align-items: center;
    gap: 1rem; /* gap-4 */
  }

  /* 课程表网格 */
  .schedule-grid {
    display: grid;
    gap: 0.5rem; /* gap-2 */
    /* height: 850px; h-32 */
  }

  /* 时间槽头部 */
  .time-slot-header {
    /* height: 2rem; h-16 */
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: #f9fafb; /* bg-gray-50 */
    font-weight: 500; /* font-medium */
  }

  /* 星期头部 */
  .day-header {
    /* height: 2rem; h-16 */
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: #f9fafb; /* bg-gray-50 */
    font-weight: 500; /* font-medium */
  }

  /* 时间槽 */
  .time-slot {
    height: auto; /* h-32 */
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: #f9fafb; /* bg-gray-50 */
    font-size: 0.875rem; /* text-sm */
    white-space: pre-line; /* whitespace-pre-line */
    text-align: center;
  }

  /* 课程单元格 */
  .course-cell {
    height: auto; /* h-32 */
    border: 1px solid #f3f4f6; /* border border-gray-100 */
    position: relative;
    padding: 0.5rem; /* p-2 */
    background-color: #ffffff; /* 可根据需要更改背景颜色 */
    cursor: pointer;
    transition: background-color 0.3s;
  }

  /* 学生标签包装器 */
  .students-wrapper {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem; /* gap-1 */
  }

  /* 学生标签 */
  .student-tag {
    background-color: #e5e7eb; /* 灰色背景 */
    border-radius: 0.25rem;
    padding: 0.25rem 0.5rem;
    font-size: 0.75rem; /* text-sm */
    margin-bottom: 0.25rem; /* mb-1 */
  }

  /* 更多标签 */
  .more-tag {
    background-color: #3b82f6;
    color: #ffffff;
  }

  /* 搜索输入框 */
  .search-input {
    width: 8rem; /* w-48 */
  }

  /* 成员列表 */
  .notices-list {
    display: flex;
    flex-direction: column;
    gap: 1rem; /* space-y-4 */
    max-height: 47rem; /* max-h-[800px] */
    overflow-y: auto;
    /* 隐藏滚动条 */
    -ms-overflow-style: none; /* IE 和 Edge */
    scrollbar-width: none; /* Firefox */

    &::-webkit-scrollbar {
      display: none; /* Chrome, Safari 和 Opera */
    }
  }

  .notices-list::-webkit-scrollbar {
    display: none; /* Chrome, Safari, Opera */
  }

  /* 通知卡片 */
  .notice-card {
    padding: 1rem; /* p-4 */
    border: 1px solid #e0e0e0; /* 更浅的边框颜色 */
    border-radius: 0.5rem; /* rounded-lg */
    transition: box-shadow 0.3s;
    background-color: #ffffff;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05); /* 更轻的阴影 */
  }

  /* 通知卡片悬停效果 */
  .notice-card:hover {
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); /* hover:shadow-md */
  }

  /* 通知头部 */
  .notice-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 0.5rem; /* mb-2 */
  }

  /* 通知标题 */
  .notice-title {
    font-weight: 600; /* font-semibold */
    color: #374151; /* text-gray-700 */
  }

  /* 通知日期 */
  .notice-date {
    font-size: 0.75rem; /* text-xs */
    color: #9ca3af; /* text-gray-400 */
  }

  /* 成员信息 */
  .member-info {
    display: flex;
    flex-direction: column;
    gap: 0.25rem; /* space-y-1 */
  }

  /* 通知内容 */
  .notice-content {
    font-size: 0.75rem; /* text-sm */
    color: #4b5563; /* text-gray-600 */
    /* padding: 0.5rem; p-2 */
    /* border-radius: 0.25rem; rounded */
    margin-bottom: 0.25rem; /* mb-1 */
  }

  /* 课程详情弹窗内容 */
  .dialog-content {
    display: flex;
    flex-direction: column;
    gap: 1rem; /* space-y-4 */
  }

  /* 课程详情内容 */
  .detail {
    display: flex;
    flex-direction: column;
  }

  /* 课程详情标签 */
  .label {
    font-size: 0.75rem; /* text-sm */
    color: #6b7280; /* text-gray-500 */
  }

  /* 课程详情值 */
  .value {
    margin-top: 0.25rem; /* mt-1 */
    font-size: 1rem;
    color: #111827;
  }

  /* 响应式设计 */
  @media (max-width: 1024px) {
    .flex-container {
      flex-direction: column;
    }

    .left-panel,
    .right-panel {
      width: 100%;
    }
  }

  /* 去掉 el-tag 的边框颜色 */
  .el-tag {
    border-color: transparent !important;
  }

  /* 课程单元格高亮 */
  .course-cell.highlight {
    animation: flash 1s ease-in-out 3;
  }

  /* 课程控制 */
  .schedule-controls {
    display: flex;
    flex-direction: column;
    align-items: center;
  }

  /* 新增样式 */
  .full-student-cell {
    background-color: #cbcccf;
  }

  .pagination-container {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 2rem;
    margin-bottom: 0;
  }
</style>
